--[[
Name: BrownieHelper
Developed by: Sonora (The Dragon Flight)
Website: http://sonora.kirintor.googlepages.com/contents
SVN: http://code.google.com/p/browniehelper/source/browse
License: GNU General Public License v3
]]

--[[
Grab bag of little utilities that really should be built into the standard
Lua library...

...and if they are and I just haven't found them yet, this gives us an easy
place to remap the calls.
]]

local __version__ = "1.0"

--t is a table, returns an integer indexed list of keys
function keys(t)
    local a = {}
    for k,v in pairs(t) do table.insert(a,k) end
    return a
end

function values(t)
    local a = {}
    for k,v in pairs(t) do table.insert(a,v) end
    return a
end

function fromValues(t, idx)
    --returns the value of .idx on every value in t
    local a = {}
    for k,v in pairs(values(t)) do table.insert(a, v[idx]) end
    return a
end

function tableRemove(t, val, all)
    --removes the val from t; if all it removes all occurences
    for i,v in ipairs(t) do
        if v==val then
            table.remove(t, i)
            if not all then return true end
        end
    end
end

function appendTables(a,b)
    --Appends the values from two tables, by returning a new table (avoids mutation)
    local ret = {}
    for k,v in pairs(a) do ret[k]=v end
    for k,v in pairs(b) do
        if ret[k]==nil then ret[k]=v
        else table.insert(ret, v)
        end
    end
    return ret
end

--t is a table to iterate over by key order, f an optional sorting func
function pairsByKeys (t, f)
    a = keys(t)
    table.sort(a, f)
    local i = 0      -- iterator variable
    local iter = function ()   -- iterator function
        i = i + 1
        if a[i] == nil then return nil
        else return a[i], t[a[i]]
        end
    end
    return iter
end

--asks if table t has a value val
function has(t, val)
    --returns bool, key where bool=true if the table has the element, and key is its index on t
    for i,v in pairs(t) do
        if v==val then return true,i end
    end
    return false
end

--Does a string based join on the values of a table
function valueJoin(t, sep)
    if sep==nil then sep=", " end
    local retstr = ""
    for i,v in pairs(t) do
        if i==#t then
            --Don't add a separator after the last element
            retstr = retstr..tostring(v)
        else
            --Add a separator to everything in the middle of the list
            retstr = retstr..tostring(v)..sep
        end
    end
    return retstr   
end

--The converse of valueJoin, does a string-based split of values to a table
function valueSplit(txt, sep)

    --If separator isn't in the string, just return the string in its own table
    if not string.find(txt, sep) then return {txt} end

    --We'll construct a table of values
    local t = {}
    
    --Track our progress through the string
    local fieldstart = 1
    
    --Cheat a little and append an extra sep to the end of the string
    txt = txt..sep
    
    --Find as many seps as we can
    repeat
        
        --Find the location of the next separator
        local nexti = string.find(txt, sep, fieldstart)
        
        --This is needed to handle possibly overlapping sep sequences
        if nexti then
            
            --Add the current position range to our table as a sting (omitting the separator)
            table.insert(t, string.sub(txt, fieldstart, nexti-1))
            
            --Update the next start position
            fieldstart = nexti + 1
            
        else
            fieldstart = string.len(txt)+1
        end
        
    until fieldstart > string.len(txt)
    return t
    
end

--Printers
function pp(obj, prepender)
    --pretty prints obj based on its type
    if prepender==nil then prepender = "DEBUG: " end
    
    if type(obj) == "number" then msg = tostring(obj).." (number)"
    elseif type(obj) == "boolean" then msg = tostring(obj).." (boolean)"
    elseif type(obj) == "table" then
        pp("start "..tostring(obj), prepender)
        for k,v in pairs(obj) do pp(tostring(k).." : "..tostring(v)) end
        msg = "end table"
    else msg = tostring(obj)
    end
    
    DEFAULT_CHAT_FRAME:AddMessage(prepender..msg)
end

--If there is no other print defined, we'll hash it to our pp'er
if not print then print = pp end

--Time and date formatting
function formatTime(hour, minute)
    --hours and minutes are integers; returns hours and minutes as strings
    if hour<10 then hour = "0"..tostring(hour)
    else hour = tostring(hour) end
    
    if minute<10 then minute = "0"..minute
    else minute = tostring(minute) end
    
    return hour, minute
end

function getFormattedGameTime()
    local hours,minutes = GetGameTime()
    local _,_,seconds = string.find(date(), ":(%d%d)$")
    
    hour,minute = formatTime(hours, minutes)
    return hour..":"..minute..":"..seconds
    
end

function getFormattedGameDateTime()
    return string.sub(date(), 1, 8).." "..getFormattedGameTime()
end

function getGameTimeMinutes()
    local hours,minutes = GetGameTime()
    return (hours*60)+minutes
end

function timeFromMinutes(mins)
    --takes mins integer and regurns hh:mm
    local hours = math.floor(mins/60)
    local minutes = mins-(hours*60)
    hours, minutes = formatTime(hours, minutes)
    return tostring(hours)..":"..tostring(minutes)
end

function minutesFromTime(time)
    --takes time string hh:mm and returns minutes integer
    local _,_,h,m = string.find(time,"(%d%d):(%d%d)")
    return (tonumber(h)*60) + tonumber(m)
end

--Seems to have been some ambiguity in the past regarding access to the global table; this stop-gap will work no matter what they do
if _G~=nil then globalTable = _G
else globalTable = getfenv()
end
